<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
      console.log(
        '%c %c\n%c测试%cMr.James', `
  `, `
  `, `
  color: #f3f3f4;
  padding: 4px 3px 4px 11px;
  background-color: #FF3D45;
  border-radius: 5px 0 0 5px;
  `, `
  color: #5A94C1;
  padding: 4px 11px 4px 3px;
  background-color: #bfd3de;
  border-radius: 0 5px 5px 0;
`)

    {
        // 1、谁调用 this指向谁
        let obj = {
            name: 'obj',
            fun: function () {
                console.log(this);//obj
            }
        };
        obj.fun();
    }
    {
        // 2、当没有人调用的时候this默认指向window
        window.fun = function () {
            console.log(this);//window
        }
        fun();
    }
    {
        //3、构造函数中的this指向构造函数本身
        function Person(name) {
            this.name = name;
            this.age = 22;
        }
        Person.prototype.say = function () {
            console.log(this);
            console.log("My name's" + this.name);
        };
        let parent = new Person('my')
        parent.say();
    }
    {
        // 4、call apply bind 强制改变方法中的this指向，第一个参数是要改变的this
        let obj = {
            birth: 2000,
            year: 2021,
            age: function () {
                console.log(this.year - this.birth);
            }
        };
        obj.age();
        // call、apply、bind 区别：
        // 执行时
        // 1、call/apply改变了函数的this上下文后马上执行该函数
        // 2、bind则是返回改变了上下文后的函数,不执行该函数
        // 返回值
        // 1、 call/apply 返回fun的执行结果
        // 2、 bind返回fun的拷贝，并指定了fun的this指向，保存了fun的参数。
        obj.age.call({
            year: 2021,
            birth: 2000
        }, 666, 888
        );

        obj.age.apply({
            year: 2021,
            birth: 2000
        }, [666, 888]
        );

        let getAgeFn = obj.age.bind({
            year: 2021,
            birth: 2000
        }, 666, 888
        );
        getAgeFn();

    }
</script>